package com.example.demo.controller;

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.example.demo.dto.FileUploadChunkDTO;
import com.example.demo.model.FileUploadCompleteData;
import com.example.demo.model.FileUploadCompleteRes;
import com.example.demo.model.FileUploadSubmitChunkRes;
import com.example.demo.model.SessionFinishData;
import com.example.demo.model.SessionFinishRes;
import com.example.demo.model.SessionInitialRes;
import com.example.demo.service.FileUploadService;

import jakarta.servlet.http.HttpServletRequest;

@RestController
@RequestMapping("/file-upload")
public class FileUploadController {

	private final FileUploadService fileUploadService;

	public FileUploadController(FileUploadService fileUploadService) {
		this.fileUploadService = fileUploadService;
	}

	@PostMapping("/initial-session")
	public SessionInitialRes initialSession() {
		SessionInitialRes response = fileUploadService.handleFileRegistration();
		return response;
	}

	@PostMapping("/submit-chunk")
	public FileUploadSubmitChunkRes submitChunk(@RequestBody byte[] chunkData, HttpServletRequest request) {
		FileUploadChunkDTO chunkDTO = extractChunkDTO(request);
		chunkDTO.setChunkData(chunkData);
		FileUploadSubmitChunkRes response;
		try {
			boolean isInspectSuccessful = fileUploadService.handleFileInspect(chunkDTO);
			boolean isUploadSuccessful = fileUploadService.handleChunkUpload(chunkDTO);
			boolean isOperationSuccessful = isInspectSuccessful && isUploadSuccessful;

			response = buildChunkUploadResponse(chunkDTO, isOperationSuccessful);
		} catch (Exception e) {
			// 发生错误时拒绝切片
			fileUploadService.handleRefuseChunk(chunkDTO.getSessionID(), chunkDTO.getChunkIndex());

			response = buildChunkUploadResponse(chunkDTO, false);
		}

		return response;
	}

	private FileUploadChunkDTO extractChunkDTO(HttpServletRequest request) {
		String sessionID = request.getHeader("Session-ID");
		String chunkIndex = request.getHeader("Chunk-Index");
		String chunkHash = request.getHeader("Chunk-hash");
		String algorithm = request.getHeader("Algorithm");

		FileUploadChunkDTO chunkDTO = new FileUploadChunkDTO(sessionID, chunkIndex, chunkHash, algorithm, null);
		return chunkDTO;
	}

	private FileUploadSubmitChunkRes buildChunkUploadResponse(FileUploadChunkDTO chunkDTO,
			boolean isOperationSuccessful) {
		FileUploadSubmitChunkRes response = new FileUploadSubmitChunkRes();
		response.setSessionID(chunkDTO.getSessionID());
		response.setChunkIndex(chunkDTO.getChunkIndex());
		response.setSucceed(isOperationSuccessful);
		return response;
	}

	@PostMapping("/complete-upload")
	public FileUploadCompleteRes completeUpload(@RequestBody FileUploadCompleteData metaData) {
		boolean isAssemblySuccessful = fileUploadService.handleFileAssembly(metaData);
		boolean isRegisterSuccessful = fileUploadService.handleFileRegister(metaData);
		boolean isOperationSuccessful = isAssemblySuccessful && isRegisterSuccessful;

		FileUploadCompleteRes response = buildCompleteUploadResponse(metaData, isOperationSuccessful);
		return response;
	}

	private FileUploadCompleteRes buildCompleteUploadResponse(FileUploadCompleteData metaData,
			boolean isOperationSuccessful) {
		FileUploadCompleteRes response = new FileUploadCompleteRes();
		response.setSessionID(metaData.getSessionID());
		response.setSuccess(isOperationSuccessful);
		return response;
	}

	@PostMapping("/finish-session")
	public SessionFinishRes finishSession(@RequestBody SessionFinishData data) {
		SessionFinishRes response = new SessionFinishRes();
		response.setSessionID(data.getSessionID());
		return response;
	}
}
